Home | | Latest | About | Random
# Week 1 Friday
Dear Class,
A new homework has been posted, tentatively due next Thursday. It uses today's ideas directly. **Please finish reading section 5 by next Monday.** Next week we start the `string` class (section 6). You got this!
-- B.
## Today's mystery: why is 17 out of 20 equal to 0%?
Imagine in one of your classes the Professor ran a program that computes a quiz percentage for you as follows. Don't run it yet. What do you expect it to print for 17 out of 20?
```cpp
#include
using namespace std;
int main(){
int correct, total;
cout << "How many questions did you get right? ";
cin >> correct;
cout << "How many questions were there? ";
cin >> total;
cout << "Your score is " << correct / total * 100 << "%.";
return 0;
}
```
- `cin >> x;` is how a program asks for input: it **pauses** until the user types a value and hits enter, then stores it in `x`. The arrow points *into* the variable, the opposite direction of `cout <<`, which sends data *out* to the screen. `std::cin` is part of the `` header.
- Run it with `17` and `20`. It prints `0%`. Try `20` and `20`: it prints `100%`. Any score below perfect prints `0%`. By the end of today you will know why, and you will know three ways to fix it.
## Integer division: `/` and `%`
**Ask yourself first.** What do you think `17 / 5` gives?
- Is it A: `3.4`, B: `3`, or C: `4`?
- And what about `17 % 5`?
With two `int`s, `/` and `%` work like grade school division with remainder. Picture 17 people and buses that each can hold 5 people:
- `17 / 5` is `3`, the number of **full buses**.This is the quotient.
- `17 % 5` is `2`, the **people left over**. This is the remainder.
The fraction part of `/` is thrown away. Both results are `int`s.
![[1-teaching/ucla-2026-fall-pic-10a/---files/17div5.png]]
**Some applications.**
- *Splitting digits.* Suppose you have a 3-digit number `137`, what could you do to split it into the first two-digit `13` and the last digit `7`?
- *Making change.* You owe someone 87 cents. How many quarters and how many cents left over? Can you figure out how many dimes fit in the remaining cents?
**Two more facts:**
- Dividing by `0` is **undefined behavior**: the language makes no promise about what happens (a crash, junk, anything). On most machines with `int`s, the program crashes. Try it at home.
- Negative numbers follow a sign rule:
- `X / Y` has a sign that is the correct mathematical sign.
- `X % Y` has a sign that matches `X`. So `%` can give negative numbers!
- `(X / Y) * Y + (X % Y)` always equals `X`.
Shortcuts: `i /= j` means `i = i / j`, and `i %= j` means `i = i % j`.
**Back to the mystery.** What is `17 / 20`? Both are `int`s, so the fraction `0.85` is thrown away and the answer is `0`. Then `0 * 100` is `0`. That is *why* we got `0%`. Fixing it needs decimals and a new tool and idea called **casting**, which we get to in Part 5.
## Decimals: `double`
`int`s can't hold `3.14`. A `double` can. A literal with a decimal point, like `0.`, `0.0`, or `3.14159`, is a `double`.
```cpp
#include
using namespace std;
int main(){
const double PI = 3.14159;
double r;
cout << "Give a radius: ";
cin >> r;
cout << "The area is " << PI * r * r;
return 0;
}
```
(`const` means the value can never change after it is set. It protects `PI` from accidents.)
- `+ - * /` work on `double`s. Try `+=` and `%` and see what happens.
- Dividing by `0.0` is also undefined behavior (some compilers give `inf`).
Need r to the 100th power? Don't type `r * r * ...` a hundred times. The function `pow(r, 100)` does it, and it lives in the `` header. When you need a function, you look it up on [cppreference.com](https://cppreference.com/). You will practice that later in Task B.
## Decimals are not exact
One warning before we use `double` everywhere. **Predict.** Is `0.1 + 0.1 + 0.1` equal to `0.3`? By default `cout` shows only about 6 digits. The manipulator `setprecision(17)` from `` asks for 17, so we can see what is really stored.
```cpp
#include
#include
using namespace std;
int main(){
double a = 0.1;
double c = 0.3;
cout << setprecision(17);
cout << a << endl;
cout << c << endl;
cout << a + a + a << endl; // ??
cout << 20.15 * 100 << endl; // ??
return 0;
}
```
The computer stores `double`s in binary, and `0.1` has no exact binary form, just as `1/3` has no exact decimal form (`0.3333...`).
- A `double` keeps about 15 to 17 significant digits and rounds the rest.
- `int`s are finite too (about plus or minus 2 billion).
**For money**, real programs avoid `double` and store whole cents in an `int`. In case `double` is unavoidable, then *rounding* can sometimes help.
## Fixing the mystery: casting
We know `17 / 20` is `0` because both are `int`s. To get `0.85`, at least one side must be a `double` before the division happens.
**Task A. Try it!** Then compare with these three fix proposals:
- `static_cast(correct) / total * 100`. This **casts** `correct` into a `double` first, so the division is a `double` division.
- `100.0 * correct / total`. Here `100.0 * correct` becomes a `double` before the division happens.
- `correct * 100 / total`. This one stays in `int`, so it avoids the zero, but it still **truncates**. Try `7` out of `9`: you get `77`, **not** `77.7778`.
**Casting rules:**
- `static_cast(n)` turns an `int n` into a `double`.
- `static_cast(x)` turns a `double x` into an `int` by **truncating** (chopping the decimals), not rounding. If you want rounding, use the `round` function (you will look it up in Task B).
**Task B. Round to one decimal place.** Store the percentage in a `double score`, then print it rounded to one decimal place (`77.7778` becomes `77.8`). You need a rounding function, so look it up on [cppreference.com](https://cppreference.com/) and answer:
- What is the function called?
- Which header does it need?
- What does it take in, and what does it return?
Then work out how to get *one decimal place* out of it. (If you're stuck: multiply first, round, then divide.)
**Double-check.** The volume of a sphere of radius `r` is $\frac{4}{3}\pi r^{3}$. Is there a bug using this C++ code
```cpp
4 / 3 * PI * pow(r, 3)
```
to calculate the volume of a sphere of radius `r`?
Assume here we already have `double PI = 3.14159;` and `double r;`
### Implicit casting: Operations mixing `double` and `int` (the reading covers the details)
- `int` with `int` stays `int`. `double` with `double` stays `double`.
- Mixing an `int` with a `double` makes the result a `double`.
- Assigning a `double` to an `int` variable truncates: `double a = 1.9; int b = a;` makes `b` equal to `1`.
- Assigning an `int` to a `double` variable is safe.
Even when C++ does this automatically, it is better practice to write the cast yourself to show your intent.
## `%` is a clock
13 o'clock is 1 o'clock, because `13 % 12 == 1`. Whenever something repeats in a cycle, `%` is the tool: days of the week, hours, turns in a game.
If you keep adding 1 to `x`, then `x % 7` cycles `0, 1, 2, 3, 4, 5, 6, 0, 1, ...`.
**Example F. Usefulness of this `%`.** Encode `0` as Sunday, `1` as Monday, ..., `6` as Saturday. **Suppose today is Friday.**
- Which day is it...
- after 3 days?
- after 10 days?
- after 3000 days?
- 10 days *before*?
- How many weeks are in 3000 days?
```cpp
#include
using namespace std;
int main(){
int day = 5; // Friday
// Finish this. Hint: / and % are both useful.
return 0;
}
```
- In case `%` gives you negative, you can add to it the length of the cycle to make it positive.
## Recap
Three things to remember from today:
1. `int / int` throws the fraction away. Cast to `double` *before* dividing.
2. A `double` is an approximation. Don't expect `0.1 + 0.1 + 0.1` to equal `0.3`.
3. `%` gives the remainder, and it cycles, so use it for anything that repeats.
## One last thing: `++` and `--`
Since it's Friday, let's end the week with the name of the language itself.
`x++` adds 1 to `x`. This is where `C++` got its name: a pun on `C = C + 1`, meaning "C, but one better." Which means that, after this week,
```cpp
week++;
```
See you Monday!
**Example D (if there is time, or try it at home).** `x++` and `++x` both add 1, but they hand back different values. Predict every line before you run it:
```cpp
#include
using namespace std;
int main(){
int x = 0;
cout << x++ << endl;
cout << x << endl;
x = 0;
cout << ++x << endl;
cout << x << endl;
return 0;
}
```
The rule:
- `x++` (post-increment): hand back a copy of the old value, *then* add 1.
- `++x` (pre-increment): add 1, *then* hand back the new value.
- `x--` and `--x` work the same way with subtraction.
A standalone `x++;` is fine. Mixing `x++` inside a bigger expression is a classic source of bugs, so avoid it.
---
Please finish reading the rest of **Section 5**, get started and try HW1, and read ahead in **Section 6.** Come to any of our office hours for questions!
I'll see you next Monday!